{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Deep Q-Network implementation (TensorFlow).\n",
    "\n",
    "In this notebook, we will implement DQN with **experience replay** and **target networks**.\n",
    "$$ \\DeclareMathOperator*{\\max}{max}$$\n",
    "### Recap\n",
    "\n",
    "Q Learning control is carried out by sampling step by step and updating Q values at each step. We use ε-greedy policy to explore and generate samples. However, the policy learnt is a deterministic greedy policy with no exploration. We can carryout updates online i.e. we take a step and use `(current state, action, reward and next_state)` tuple to update. \n",
    "\n",
    "In case of function approximation using neural network, the input to the network is the state and output is the q(s,a) for all the actions in the state `s`. It is denoted as $ \\hat{q}(s_t,a; w_{t}) $, where $w_{t}$ is the weights of the neural network which we are trying to learn as part of DQN learning. \n",
    "\n",
    "We use two networks, one target network to get the max q-value of next state denoted by $ \\max_a \\hat {q}(s_{t+1},a; w^{-}_{t}) $ and the primary network (online network) with weights $w_{t}$ which we are updated based on back propagation of the TD error through the network.\n",
    "\n",
    "The Update equation is given below. This is the online version:\n",
    "$$ w_{t+1} \\leftarrow w_t + \\alpha [ R_{t+1} + \\gamma . \\max_{a} \\hat{q}(S_{t+1},a,w^{-}_{t}) – \\hat{q}(S_t,A_t,w_t)] \\nabla \\hat{q}(S_t,A_t,w_t)$$\n",
    "\n",
    "Online update with neural network with millions of weights does not work well. Accordingly, We use experience replay (aka Replay Buffer).  We use a behavior policy to explore the environment and store the samples `(s, a, r, s', done)` in a buffer. The samples are generated using an exploratory behavior policy while we improve a deterministic target policy using q-values. \n",
    "\n",
    "Therefore, we can always use older samples from behavior policy and apply them again and again. We can keep the buffer size fixed to some pre-determined size and keep deleting the older samples as we collect new ones. This process makes learning sample efficient by reusing a sample multiple times and also removing temporal dependence of the samples we would otherwise see while following a trajectory.\n",
    "\n",
    "The update equation with batch update with minor modifications is given below. We collect samples of transitions (current state, action, reward, next state) in a buffer. Where each sample is denoted as a tuple: \n",
    "\n",
    "$$ (s_{i}, a_{i}, r_{i}, s^{'}_{i}, done_{i})$$\n",
    "\n",
    "Subscript (i) denotes ith sample. We take N samples from experience replay selecting randomly and update the weights. Subscript (t) denotes the index of weight updates. If the current state is done, as denoted by `done` flag, the target is just the reward as terminal states have zero value. The final update equation is as given below:\n",
    "\n",
    "$$w_{t+1} \\leftarrow w_t + \\alpha \\frac{1}{N} \\sum_{i=1}^{N} \\left[ r_i + \\left( (1-done_i) . \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t}) \\right) – \\hat{q}(s_i,a_i;w_t) \\right] \\nabla \\hat{q}(s_i,a_i;w_t)$$\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Dense, Flatten\n",
    "from tensorflow.keras import Model\n",
    "import gym\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.signal import convolve, gaussian\n",
    "\n",
    "import os\n",
    "import io\n",
    "import base64\n",
    "import time\n",
    "import glob\n",
    "from IPython.display import HTML\n",
    "\n",
    "%matplotlib inline\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Environment - CartPole \n",
    "\n",
    "We can use the setup here to run on any environment which has state as a single vector and actions are discrete. We will build it on Cart Pole and they try to run this on many other environments like Atari games and others."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_env(env_name, seed=None):\n",
    "    # remove time limit wrapper from environment\n",
    "    env = gym.make(env_name).unwrapped\n",
    "    if seed is not None:\n",
    "        env.seed(seed)\n",
    "    return env"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAD8CAYAAABXe05zAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAASvklEQVR4nO3df6zd9X3f8efLxpioBmHqCzP+MdzMrDVRa6o7l4lpYklWPDbV5A8mR1rmP5CcP8iSaFU23Epr8oeVbGrIpGiJ5CyoVpbGsUSorSjrSr1EKFOHY1IgNsbFDQ5c7OBrp6lhLI5/vPfH/XqcmHt9j+8PXT73PB/S0fme9/l+z3m/EX7x5ePvOSdVhSSpHQvmugFJ0tUxuCWpMQa3JDXG4JakxhjcktQYg1uSGjNrwZ1kY5IjSY4meXi23keSBk1m4zruJAuBvwL+KTACfA/4YFU9P+NvJkkDZrbOuDcAR6vqh1X1c2AXsGmW3kuSBso1s/S6K4BXeh6PAL810c7Lli2r2267bZZakaT2HDt2jFOnTmW852YruMd7s19Yk0myFdgKsHr1ag4cODBLrUhSe4aHhyd8braWSkaAVT2PVwLHe3eoqh1VNVxVw0NDQ7PUhiTNP7MV3N8D1iZZk+RaYDOwd5beS5IGyqwslVTV+SQfAf4HsBB4tKoOzcZ7SdKgma01bqrqW8C3Zuv1JWlQ+clJSWqMwS1JjTG4JakxBrckNcbglqTGGNyS1BiDW5IaY3BLUmMMbklqjMEtSY0xuCWpMQa3JDXG4JakxhjcktQYg1uSGmNwS1JjDG5JaozBLUmNmdZPlyU5BrwOXADOV9VwkpuArwO3AceAf1lVfzO9NiVJl8zEGfc/qar1VTXcPX4Y2FdVa4F93WNJ0gyZjaWSTcDObnsncP8svIckDazpBncBf5bk6SRbu9otVXUCoLu/eZrvIUnqMa01buDuqjqe5GbgiSQv9HtgF/RbAVavXj3NNiRpcEzrjLuqjnf3J4HHgQ3Aa0mWA3T3Jyc4dkdVDVfV8NDQ0HTakKSBMuXgTvJLSa6/tA38NnAQ2Ats6XbbAuyZbpOSpLdMZ6nkFuDxJJde54+r6k+TfA/YneRB4GXggem3KUm6ZMrBXVU/BH5jnPpp4H3TaUqSNDE/OSlJjTG4JakxBrckNcbglqTGGNyS1BiDW5IaY3BLUmMMbklqjMEtSY0xuCWpMQa3JDXG4JakxhjcktQYg1uSGmNwS1JjDG5JaozBLUmNMbglqTEGtyQ1ZtLgTvJokpNJDvbUbkryRJIXu/ulPc9tS3I0yZEk985W45I0qPo54/4jYONltYeBfVW1FtjXPSbJOmAzcEd3zBeSLJyxbiVJkwd3VT0J/OSy8iZgZ7e9E7i/p76rqs5W1UvAUWDDzLQqSYKpr3HfUlUnALr7m7v6CuCVnv1GutrbJNma5ECSA6Ojo1NsQ5IGz0z/5WTGqdV4O1bVjqoarqrhoaGhGW5DkuavqQb3a0mWA3T3J7v6CLCqZ7+VwPGptydJutxUg3svsKXb3gLs6alvTrI4yRpgLbB/ei1KknpdM9kOSb4G3AMsSzIC/AHwGWB3kgeBl4EHAKrqUJLdwPPAeeChqrowS71L0kCaNLir6oMTPPW+CfbfDmyfTlOSpIn5yUlJaozBLUmNMbglqTEGtyQ1xuCWpMYY3JLUGINbkhpjcEtSYwxuSWqMwS1JjTG4JakxBrckNcbglqTGGNyS1BiDW5IaY3BLUmMMbklqjMEtSY2ZNLiTPJrkZJKDPbVPJnk1yTPd7b6e57YlOZrkSJJ7Z6txSRpU/Zxx/xGwcZz656pqfXf7FkCSdcBm4I7umC8kWThTzUqS+gjuqnoS+Emfr7cJ2FVVZ6vqJeAosGEa/UmSLjOdNe6PJHmuW0pZ2tVWAK/07DPS1d4mydYkB5IcGB0dnUYbkjRYphrcXwTeDawHTgCf7eoZZ98a7wWqakdVDVfV8NDQ0BTbkKTBM6XgrqrXqupCVV0EvsRbyyEjwKqeXVcCx6fXoiSp15SCO8nynocfAC5dcbIX2JxkcZI1wFpg//RalCT1umayHZJ8DbgHWJZkBPgD4J4k6xlbBjkGfBigqg4l2Q08D5wHHqqqC7PSuSQNqEmDu6o+OE75y1fYfzuwfTpNSZIm5icnJakxBrckNcbglqTGGNyS1BiDW5IaM+lVJdIgePP0COd/9gaLr1/G4huWzXU70hUZ3BJw/MBe/vZHz7L4hiEW3zD2FQzXLb2VVf/wgTnuTHo7g1vqcfbMKGfPjH3p2YVzZ+e4G2l8rnFLUmMMbklqjMEtSY0xuCWpMQa3JDXG4JakxhjcktQYg1uSGmNwS1JjDG5JasykwZ1kVZJvJzmc5FCSj3X1m5I8keTF7n5pzzHbkhxNciTJvbM5gCQNmn7OuM8Dv1tVvwbcBTyUZB3wMLCvqtYC+7rHdM9tBu4ANgJfSLJwNpqXpEE0aXBX1Ymq+n63/TpwGFgBbAJ2drvtBO7vtjcBu6rqbFW9BBwFNsxw35I0sK5qjTvJbcCdwFPALVV1AsbCHbi5220F8ErPYSNd7fLX2prkQJIDo6OjU2hdkgZT38GdZAnwGPDxqjpzpV3HqdXbClU7qmq4qoaHhob6bUOSBl5fwZ1kEWOh/dWq+kZXfi3J8u755cDJrj4CrOo5fCVwfGbalST1c1VJgC8Dh6vqkZ6n9gJbuu0twJ6e+uYki5OsAdYC+2euZUkabP38As7dwIeAHyR5pqv9HvAZYHeSB4GXgQcAqupQkt3A84xdkfJQVV2Y6cYlaVBNGtxV9V3GX7cGeN8Ex2wHtk+jL0nSBPzkpCQ1xuCWpMYY3JLUGINbkhpjcEtSYwxuDby6eIG6+PYrVhdcc+0cdCNNzuDWwHvz1MucGXn+bfW/s37jHHQjTc7g1sCrixehLr6tvmDhojnoRpqcwS1JjTG4JakxBrckNcbglqTGGNyS1BiDW5IaY3BLUmMMbklqjMEtSY0xuCWpMf38WPCqJN9OcjjJoSQf6+qfTPJqkme62309x2xLcjTJkST3zuYAkjRo+vmx4PPA71bV95NcDzyd5Inuuc9V1R/27pxkHbAZuAO4FfjzJLf7g8GSNDMmPeOuqhNV9f1u+3XgMLDiCodsAnZV1dmqegk4CmyYiWYlSVe5xp3kNuBO4Kmu9JEkzyV5NMnSrrYCeKXnsBGuHPSSpKvQd3AnWQI8Bny8qs4AXwTeDawHTgCfvbTrOIfXOK+3NcmBJAdGR0evtm9JGlh9BXeSRYyF9ler6hsAVfVaVV2oqovAl3hrOWQEWNVz+Erg+OWvWVU7qmq4qoaHhoamM4MkDZR+rioJ8GXgcFU90lNf3rPbB4CD3fZeYHOSxUnWAGuB/TPXsiQNtn6uKrkb+BDwgyTPdLXfAz6YZD1jyyDHgA8DVNWhJLuB5xm7IuUhryiRpJkzaXBX1XcZf936W1c4ZjuwfRp9SZIm4CcnJakxBrckNcbglqTGGNyS1BiDW5IaY3BLUmMMbklqjMEtSY0xuCWpMQa3JDXG4JakxhjcktQYg1uSGtPP17pKzXn11Vf56Ec/ysWLFyfdd+WNi9hy11Jy2Xdgbtu2jZGfnpv0+AULFvD5z3+eW2+9dartSlfF4Na89MYbb7Bnzx4uXJj8q+B//Vdu4V/fdT8/v3Dd/68tWvAznnzySZ774WuTHr9w4UI+/elPT6tf6WoY3Bp4RfjRm+t44fV/wNhXzxe/dv1+4E/mtjFpAga3Bt7fnlvG4TO/xcWePw4vv/mrnL34rjnsSpqYfzmpgVcs4EIt/IXamfPLePPCDXPUkXRl/fxY8HVJ9id5NsmhJJ/q6jcleSLJi9390p5jtiU5muRIkntncwBpuhbmHNcuOPsLtZsWneD6a34yRx1JV9bPGfdZ4L1V9RvAemBjkruAh4F9VbUW2Nc9Jsk6YDNwB7AR+EKSheO9sPROsLhOcuPP/oRTp17i3P/9MUuu+RveveRZrsnkV5RIc6GfHwsu4I3u4aLuVsAm4J6uvhP4DvDvu/quqjoLvJTkKLAB+IuJ3uPcuXP8+Mc/ntoE0jhOnTrF2L+6kzvyymn+zWc+SxF+dfUy/v7qX+Z/ASOjZ67q/W64waUVzZxz5yY+cejrLye7M+angb8H/JeqeirJLVV1AqCqTiS5udt9BfC/ew4f6WoTOn36NF/5ylf6aUXqy+joaN/BDXCxCigO/+gkh3908qre6+LFi+zZs4dly5ZdZZfSxE6fPj3hc30Fd1VdANYnuRF4PMl7rrB7xqm97U9Qkq3AVoDVq1fziU98op9WpL4cOXKERx55pK/ruKdrwYIFPPjgg9x+++2z/l4aHF//+tcnfO6qriqpqp8ytiSyEXgtyXKA7v7SacoIsKrnsJXA8XFea0dVDVfV8NDQ0NW0IUkDrZ+rSoa6M22SvAt4P/ACsBfY0u22BdjTbe8FNidZnGQNsBbYP8N9S9LA6mepZDmws1vnXgDsrqpvJvkLYHeSB4GXgQcAqupQkt3A88B54KFuqUWSNAP6uarkOeDOceqngfdNcMx2YPu0u5MkvY2fnJSkxhjcktQYv2RK89KSJUvYtGlTX9/HPV0LFixgyZIls/4+0iUGt+alFStW8Nhjj811G9KscKlEkhpjcEtSYwxuSWqMwS1JjTG4JakxBrckNcbglqTGGNyS1BiDW5IaY3BLUmMMbklqjMEtSY0xuCWpMQa3JDWmnx8Lvi7J/iTPJjmU5FNd/ZNJXk3yTHe7r+eYbUmOJjmS5N7ZHECSBk0/38d9FnhvVb2RZBHw3ST/vXvuc1X1h707J1kHbAbuAG4F/jzJ7f5gsCTNjEnPuGvMG93DRd2trnDIJmBXVZ2tqpeAo8CGaXcqSQL6XONOsjDJM8BJ4Imqeqp76iNJnkvyaJKlXW0F8ErP4SNdTZI0A/oK7qq6UFXrgZXAhiTvAb4IvBtYD5wAPtvtnvFe4vJCkq1JDiQ5MDo6OoXWJWkwXdVVJVX1U+A7wMaqeq0L9IvAl3hrOWQEWNVz2Erg+DivtaOqhqtqeGhoaCq9S9JA6ueqkqEkN3bb7wLeD7yQZHnPbh8ADnbbe4HNSRYnWQOsBfbPaNeSNMD6uapkObAzyULGgn53VX0zyVeSrGdsGeQY8GGAqjqUZDfwPHAeeMgrSiRp5kwa3FX1HHDnOPUPXeGY7cD26bUmSRqPn5yUpMYY3JLUGINbkhpjcEtSYwxuSWqMwS1JjTG4JakxBrckNcbglqTGGNyS1BiDW5IaY3BLUmMMbklqjMEtSY0xuCWpMQa3JDXG4JakxhjcktQYg1uSGmNwS1JjDG5JaozBLUmNSVXNdQ8kGQX+D3BqrnuZBctwrtbM19mcqy1/t6qGxnviHRHcAEkOVNXwXPcx05yrPfN1NueaP1wqkaTGGNyS1Jh3UnDvmOsGZolztWe+zuZc88Q7Zo1bktSfd9IZtySpD3Me3Ek2JjmS5GiSh+e6n6uV5NEkJ5Mc7KndlOSJJC9290t7ntvWzXokyb1z0/XkkqxK8u0kh5McSvKxrt70bEmuS7I/ybPdXJ/q6k3PdUmShUn+Msk3u8fzZa5jSX6Q5JkkB7ravJhtSqpqzm7AQuCvgV8BrgWeBdbNZU9TmOEfA78JHOyp/Sfg4W77YeA/dtvruhkXA2u62RfO9QwTzLUc+M1u+3rgr7r+m54NCLCk214EPAXc1fpcPfP9W+CPgW/Ol38Xu36PAcsuq82L2aZym+sz7g3A0ar6YVX9HNgFbJrjnq5KVT0J/OSy8iZgZ7e9E7i/p76rqs5W1UvAUcb+GbzjVNWJqvp+t/06cBhYQeOz1Zg3uoeLulvR+FwASVYC/xz4rz3l5ue6gvk82xXNdXCvAF7peTzS1Vp3S1WdgLEABG7u6k3Om+Q24E7Gzk6bn61bTngGOAk8UVXzYi7gPwP/DrjYU5sPc8HYf1z/LMnTSbZ2tfky21W7Zo7fP+PU5vNlLs3Nm2QJ8Bjw8ao6k4w3wtiu49TekbNV1QVgfZIbgceTvOcKuzcxV5J/AZysqqeT3NPPIePU3nFz9bi7qo4nuRl4IskLV9i3tdmu2lyfcY8Aq3oerwSOz1EvM+m1JMsBuvuTXb2peZMsYiy0v1pV3+jK82I2gKr6KfAdYCPtz3U38DtJjjG25PjeJP+N9ucCoKqOd/cngccZW/qYF7NNxVwH9/eAtUnWJLkW2AzsneOeZsJeYEu3vQXY01PfnGRxkjXAWmD/HPQ3qYydWn8ZOFxVj/Q81fRsSYa6M22SvAt4P/ACjc9VVduqamVV3cbYn6P/WVX/isbnAkjyS0muv7QN/DZwkHkw25TN9d+OAvcxdsXCXwO/P9f9TKH/rwEngHOM/Zf+QeCXgX3Ai939TT37/3436xHgn811/1eY6x8x9r+XzwHPdLf7Wp8N+HXgL7u5DgL/oas3PddlM97DW1eVND8XY1edPdvdDl3Kifkw21RvfnJSkhoz10slkqSrZHBLUmMMbklqjMEtSY0xuCWpMQa3JDXG4JakxhjcktSY/wcn25J5nKmL0wAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "env_name = 'CartPole-v1'\n",
    "\n",
    "env = make_env(env_name)\n",
    "env.reset()\n",
    "plt.imshow(env.render(\"rgb_array\"))\n",
    "state_shape, n_actions = env.observation_space.shape, env.action_space.n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Building a network using tensorflow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us build a DQN agent using a simple network. We now need to build a neural network that can map states/observations to state q-values. The observation space and action space is as given below for CartPole\n",
    "\n",
    "    Observation:\n",
    "        Type: Box(4)\n",
    "        Num     Observation               Min                     Max\n",
    "        0       Cart Position             -4.8                    4.8\n",
    "        1       Cart Velocity             -Inf                    Inf\n",
    "        2       Pole Angle                -0.418 rad (-24 deg)    0.418 rad (24 deg)\n",
    "        3       Pole Angular Velocity     -Inf                    Inf\n",
    "    Actions:\n",
    "        Type: Discrete(2)\n",
    "        Num   Action\n",
    "        0     Push cart to the left\n",
    "        1     Push cart to the right\n",
    "        \n",
    "\n",
    "The model will be a simple one with 2 hidden layers with Relu activation and final layer being logits with dimension equal to number of actions. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class DQNAgent:\n",
    "    def __init__(self, state_shape, n_actions, epsilon=0):\n",
    "        self.epsilon = epsilon\n",
    "        self.n_actions = n_actions\n",
    "        self.state_shape = state_shape\n",
    "\n",
    "        state_dim = state_shape[0]\n",
    "        self.model = tf.keras.models.Sequential()\n",
    "        self.model.add(tf.keras.Input(shape=(state_dim,)))\n",
    "        self.model.add(tf.keras.layers.Dense(192, activation='relu'))\n",
    "        self.model.add(tf.keras.layers.Dense(256, activation='relu'))\n",
    "        self.model.add(tf.keras.layers.Dense(64, activation='relu'))\n",
    "        self.model.add(tf.keras.layers.Dense(n_actions))\n",
    "    \n",
    "    def __call__(self, state_t):\n",
    "        # pass the state at time t through the newrok to get Q(s,a)\n",
    "        qvalues = self.model(state_t)\n",
    "        return qvalues\n",
    "\n",
    "    def get_qvalues(self, states):\n",
    "        # input is an array of states in numpy and outout is Qvals as numpy array\n",
    "        qvalues = self.model(states)\n",
    "        return qvalues.numpy()\n",
    "\n",
    "    def sample_actions(self, qvalues):\n",
    "        # sample actions from a batch of q_values using epsilon greedy policy\n",
    "        epsilon = self.epsilon\n",
    "        batch_size, n_actions = qvalues.shape\n",
    "        random_actions = np.random.choice(n_actions, size=batch_size)\n",
    "        best_actions = qvalues.argmax(axis=-1)\n",
    "        should_explore = np.random.choice(\n",
    "            [0, 1], batch_size, p=[1-epsilon, epsilon])\n",
    "        return np.where(should_explore, random_actions, best_actions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = DQNAgent(state_shape, n_actions, epsilon=0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense (Dense)                (None, 192)               960       \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 256)               49408     \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 64)                16448     \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 2)                 130       \n",
      "=================================================================\n",
      "Total params: 66,946\n",
      "Trainable params: 66,946\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "agent.model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate(env, agent, n_games=1, greedy=False, t_max=10000):\n",
    "    rewards = []\n",
    "    for _ in range(n_games):\n",
    "        s = env.reset()\n",
    "        reward = 0\n",
    "        for _ in range(t_max):\n",
    "            qvalues = agent.get_qvalues(np.array([s]))\n",
    "            action = qvalues.argmax(axis=-1)[0] if greedy else agent.sample_actions(qvalues)[0]\n",
    "            s, r, done, _ = env.step(action)\n",
    "            reward += r\n",
    "            if done:\n",
    "                break\n",
    "\n",
    "        rewards.append(reward)\n",
    "    return np.mean(rewards)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "evaluate(env, agent, n_games=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "env.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prioritized Experience replay\n",
    "\n",
    "In this notebook, we will use `Prioritized` version replay buffer as explained in the paper https://arxiv.org/pdf/1511.05952.pdf. \n",
    "\n",
    "Replay buffer is very important in DQN to break the correlation between samples. We use a behavior policy ($\\epsilon-greedy$) to sample from the environment and store the transitions (s,a,r,s',done) into a buffer. These samples are used multiple times in a learning making the process sample efficient. \n",
    "\n",
    "We will be using prioritized version of experience replay. \n",
    "\n",
    "The interface to PrioritizedReplayBuffer is:\n",
    "* `exp_replay.add(state, action, reward, next_state, done)` - saves (s,a,r,s',done) tuple into the buffer\n",
    "* `exp_replay.sample(batch_size)` - returns states, actions, rewards, next_states and done_flags for `batch_size` random samples.\n",
    "* `update_priorities(idxs, new_priorities)` - returns nothing. \n",
    "* `len(exp_replay)` - returns number of elements stored in replay buffer.\n",
    "\n",
    "IN usual replay buffer, we select training batch with equal pronability of selection for each sample/transition stored in the buffer. However, in Prioritized replay, we assign an importance score $p_i$ to each sample/transition. One approach to importance score is to use the absolute value of TD error $\\delta_i$ with addition of small constant $\\epsilon$ to avoid the edge case of error being zero and not picked up again ever.  \n",
    "\n",
    "$$ p_i = |\\delta_i| +\\epsilon$$\n",
    "\n",
    "$$\\delta_i = r_i + \\left( (1-done_i) . \\gamma .  \\max_{a^{'}_{i}} \\hat{q}(s_{i}^{'},a_{i}^{'};w^{-}_{t}) \\right) – \\hat{q}(s_i,a_i;w_t)$$\n",
    "\n",
    "\n",
    "At the time of picking the batch samples from buffer, the individual importance scores for samples are converted to probability which defines the probability of a sample being picked:\n",
    "\n",
    "$$P(i) = \\frac{p_i^{\\alpha}}{\\sum_i p_i^{\\alpha}}; \\alpha=0.6 $$\n",
    "\n",
    "$\\alpha$ is a hyper parameter and in the paper cited above, a value of 0.6 was found to work the best. We are using the same value in our code below:\n",
    "\n",
    "\n",
    "TD error for the samples chosen in the batch is used to calculate the loss and $\\nabla_w(L)$. The TD error is also used to update the importance score $p_i$ of the samples back in the buffer. \n",
    "\n",
    "\n",
    "The probability $P(i)$ is also used to calculate a weight, an importance sampling value, to adjust for the fact that samples now have a non uniform probability of being picked. The weight vector for batch samples as given below:\n",
    "\n",
    "$$w_i = \\left(\\frac{1}{N}.\\frac{1}{P(i)} \\right)^\\beta; \\beta=0.4$$\n",
    "\n",
    "Value of $\\beta=0.4$ has been taken from the paper cited above. \n",
    "\n",
    "While calculating the training loss, the individual TD errors $\\delta_i$ are weighed by the weights $w_i$. The updated batch loss equation is shown a few cells below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "class PrioritizedReplayBuffer:\n",
    "    def __init__(self, size, alpha=0.6, beta=0.4):\n",
    "        self.size = size #max number of items in buffer\n",
    "        self.buffer =[] #array to holde buffer\n",
    "        self.next_id = 0\n",
    "        self.alpha = alpha\n",
    "        self.beta = beta\n",
    "        self.priorities = np.ones(size)\n",
    "        self.epsilon = 1e-5\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.buffer)\n",
    "    \n",
    "    def add(self, state, action, reward, next_state, done):\n",
    "        item = (state, action, reward, next_state, done)\n",
    "        max_priority = self.priorities.max()\n",
    "        if len(self.buffer) < self.size:\n",
    "           self.buffer.append(item)\n",
    "        else:\n",
    "            self.buffer[self.next_id] = item\n",
    "        self.priorities[self.next_id] = max_priority\n",
    "        self.next_id = (self.next_id + 1) % self.size\n",
    "        \n",
    "    def sample(self, batch_size):\n",
    "        priorities = self.priorities[:len(self.buffer)]\n",
    "        probabilities = priorities ** self.alpha\n",
    "        probabilities /= probabilities.sum()\n",
    "        N = len(self.buffer)\n",
    "        weights = (N * probabilities) ** (-self.beta)\n",
    "        weights /= weights.max()\n",
    "\n",
    "        idxs = np.random.choice(len(self.buffer), batch_size, p=probabilities)\n",
    "\n",
    "        samples = [self.buffer[i] for i in idxs]\n",
    "        states, actions, rewards, next_states, done_flags = list(zip(*samples))\n",
    "        weights = weights[idxs]\n",
    "        \n",
    "        \n",
    "        return  (np.array(states), np.array(actions), np.array(rewards), \n",
    "                np.array(next_states), np.array(done_flags), np.array(weights), np.array(idxs))\n",
    "        \n",
    "    def update_priorities(self, idxs, new_priorities):\n",
    "        self.priorities[idxs] = new_priorities+self.epsilon"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def play_and_record(start_state, agent, env, exp_replay, n_steps=1):\n",
    "\n",
    "    s = start_state\n",
    "    sum_rewards = 0\n",
    "\n",
    "    # Play the game for n_steps and record transitions in buffer\n",
    "    for _ in range(n_steps):\n",
    "        qvalues = agent.get_qvalues(np.array([s]))\n",
    "        a = agent.sample_actions(qvalues)[0]        \n",
    "        next_s, r, done, _ = env.step(a)\n",
    "        sum_rewards += r\n",
    "        exp_replay.add(s, a, r, next_s, done)\n",
    "        if done:\n",
    "            s = env.reset()\n",
    "        else:\n",
    "            s = next_s\n",
    "        \n",
    "    return sum_rewards, s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Target network\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "target_network = DQNAgent(agent.state_shape, agent.n_actions, epsilon=0.5)\n",
    "target_network.model.set_weights(agent.model.get_weights())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Learning with... Q-learning\n",
    "Here we write a function similar to tabular q-learning. We will calculate average TD error per batch using the equation: \n",
    "\n",
    "$$ L =  \\frac{1}{N} \\sum_{i=1}^{N} \\left[ r_i + \\left( (1-done_i) . \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t}) \\right) – \\hat{q}(s_i,a_i;w_t) \\right]^2$$\n",
    "\n",
    "\n",
    "$$ \\nabla_w L =   - \\frac{1}{N} \\sum_{i=1}^{N} \\left[ r_i + \\left( (1-done_i) . \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t}) \\right) – \\hat{q}(s_i,a_i;w_t) \\right] \\nabla \\hat{q}(s_i,a_i;w_t)$$\n",
    "\n",
    "\n",
    "$\\hat{q}(s',A;w^{-})$ is calculated using target network whose weights are held constant and refreshed periodically from the agent learning network. \n",
    "\n",
    "Target is given by following:\n",
    "* non terminal state: $r_i +  \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t})$\n",
    "* terminal state: $ r_i $\n",
    "\n",
    "We then carryout back propagation through the agent network to update the weights using equation below:\n",
    "\n",
    "\n",
    "$$ \n",
    "\\DeclareMathOperator*{\\max}{max} w_{t+1} \\leftarrow w_t - \\alpha \\nabla_{w}L$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_td_loss_priority_replay(agent, target_network, replay_buffer,\n",
    "                    states, actions, rewards, next_states, done_flags, weights, buffer_idxs,\n",
    "                    gamma=0.99):\n",
    "\n",
    "    # get q-values for all actions in current states\n",
    "    # use agent network\n",
    "    predicted_qvalues = agent(states)\n",
    "\n",
    "    # compute q-values for all actions in next states\n",
    "    # use target network\n",
    "    predicted_next_qvalues = target_network(next_states)\n",
    "    \n",
    "    # select q-values for chosen actions\n",
    "    row_indices= tf.range(len(actions))\n",
    "    indices = tf.transpose([row_indices, actions])\n",
    "    predicted_qvalues_for_actions = tf.gather_nd(predicted_qvalues, indices)\n",
    "    \n",
    "\n",
    "    # compute Qmax(next_states, actions) using predicted next q-values\n",
    "    next_state_values = tf.reduce_max(predicted_next_qvalues, axis=1)\n",
    "\n",
    "    # compute \"target q-values\" \n",
    "    target_qvalues_for_actions = rewards + gamma * next_state_values * (1-done_flags)\n",
    "\n",
    "    # weighted mean squared error loss to minimize\n",
    "    loss = (target_qvalues_for_actions - predicted_qvalues_for_actions) ** 2 * weights\n",
    "    loss = tf.reduce_mean(loss)\n",
    "    \n",
    "    # calculate new priorities and update buffer\n",
    "    new_priorities = (target_qvalues_for_actions - predicted_qvalues_for_actions).numpy().copy()\n",
    "    new_priorities = np.absolute(new_priorities)\n",
    "    replay_buffer.update_priorities(buffer_idxs, new_priorities)\n",
    "    \n",
    "    return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Main loop\n",
    "\n",
    "We now carryout the training on DQN setup above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tqdm import trange\n",
    "from IPython.display import clear_output\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# set a seed\n",
    "seed = 13\n",
    "random.seed(seed)\n",
    "np.random.seed(seed)\n",
    "tf.random.set_seed(seed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "#setup env and agent and target networks\n",
    "env_name = 'CartPole-v1'\n",
    "env = make_env(env_name, seed)\n",
    "state_dim = env.observation_space.shape\n",
    "n_actions = env.action_space.n\n",
    "state = env.reset()\n",
    "\n",
    "agent = DQNAgent(state_dim, n_actions, epsilon=1)\n",
    "target_network = DQNAgent(state_dim, n_actions, epsilon=1)\n",
    "target_network.model.set_weights(agent.model.get_weights())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000\n"
     ]
    }
   ],
   "source": [
    "# let us fill experience replay with some samples using full random policy\n",
    "exp_replay = PrioritizedReplayBuffer(10**4)\n",
    "for i in range(100):\n",
    "    play_and_record(state, agent, env, exp_replay, n_steps=10**2)\n",
    "    if len(exp_replay) == 10**4:\n",
    "        break\n",
    "print(len(exp_replay))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "#setup some parameters for training\n",
    "timesteps_per_epoch = 1\n",
    "batch_size = 32\n",
    "total_steps = 45000\n",
    "\n",
    "#init Optimizer\n",
    "optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4)\n",
    "# set exploration epsilon \n",
    "start_epsilon = 1\n",
    "end_epsilon = 0.05\n",
    "eps_decay_final_step = 2 * 10**4\n",
    "\n",
    "# setup spme frequency for loggind and updating target network\n",
    "loss_freq = 20\n",
    "refresh_target_network_freq = 100\n",
    "eval_freq = 1000\n",
    "\n",
    "# to clip the gradients\n",
    "max_grad_norm = 5000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "mean_rw_history = []\n",
    "td_loss_history = []\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def epsilon_schedule(start_eps, end_eps, step, final_step):\n",
    "    return start_eps + (end_eps-start_eps)*min(step, final_step)/final_step\n",
    "\n",
    "def smoothen(values):\n",
    "    kernel = gaussian(100, std=100)\n",
    "    kernel = kernel / np.sum(kernel)\n",
    "    return convolve(values, kernel, 'valid')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "buffer size = 10000, epsilon = 0.05000\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1152x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████| 45001/45001 [11:09<00:00, 67.22it/s]\n"
     ]
    }
   ],
   "source": [
    "state = env.reset()\n",
    "for step in trange(total_steps + 1):\n",
    "    \n",
    "    # reduce exploration as we progress\n",
    "    agent.epsilon = epsilon_schedule(start_epsilon, end_epsilon, step, eps_decay_final_step)\n",
    "\n",
    "    # take timesteps_per_epoch and update experience replay buffer\n",
    "    _, state = play_and_record(state, agent, env, exp_replay, timesteps_per_epoch)\n",
    "\n",
    "    # train by sampling batch_size of data from experience replay\n",
    "    states, actions, rewards, next_states, done_flags, weights, idxs = exp_replay.sample(batch_size)\n",
    "    \n",
    "    with tf.GradientTape() as tape:\n",
    "        # loss = <compute TD loss>\n",
    "        loss = compute_td_loss_priority_replay(\n",
    "                    agent, target_network, exp_replay,\n",
    "                    states, actions, rewards, next_states, done_flags, weights, idxs,              \n",
    "                    gamma=0.99)\n",
    "\n",
    "    gradients = tape.gradient(loss, agent.model.trainable_variables)\n",
    "    clipped_grads = [tf.clip_by_norm(g, max_grad_norm) for g in gradients]\n",
    "    optimizer.apply_gradients(zip(clipped_grads, agent.model.trainable_variables))\n",
    "\n",
    "\n",
    "    if step % loss_freq == 0:\n",
    "        td_loss_history.append(loss.numpy())\n",
    "\n",
    "    if step % refresh_target_network_freq == 0:\n",
    "        # Load agent weights into target_network\n",
    "        target_network.model.set_weights(agent.model.get_weights())\n",
    "\n",
    "    if step % eval_freq == 0:\n",
    "        # eval the agent\n",
    "        mean_rw_history.append(evaluate(\n",
    "            make_env(env_name, seed=step), agent, n_games=3, greedy=True, t_max=1000)\n",
    "        )\n",
    "\n",
    "        clear_output(True)\n",
    "        print(\"buffer size = %i, epsilon = %.5f\" %\n",
    "              (len(exp_replay), agent.epsilon))\n",
    "\n",
    "        plt.figure(figsize=[16, 5])\n",
    "        plt.subplot(1, 2, 1)\n",
    "        plt.title(\"Mean reward per episode\")\n",
    "        plt.plot(mean_rw_history)\n",
    "        plt.grid()\n",
    "\n",
    "        assert not np.isnan(td_loss_history[-1])\n",
    "        plt.subplot(1, 2, 2)\n",
    "        plt.title(\"TD loss history (smoothened)\")\n",
    "        plt.plot(smoothen(td_loss_history))\n",
    "        plt.grid()\n",
    "\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "final score: 359.56666666666666\n",
      "Well done\n"
     ]
    }
   ],
   "source": [
    "final_score = evaluate(\n",
    "  make_env(env_name),\n",
    "  agent, n_games=30, greedy=True, t_max=1000\n",
    ")\n",
    "print('final score:', final_score)\n",
    "print('Well done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Let us record a video of trained agent**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_animation(env, agent, save_dir):\n",
    "    \n",
    "    try:\n",
    "        env = gym.wrappers.Monitor(\n",
    "            env, save_dir, video_callable=lambda id: True, force=True, mode='evaluation')\n",
    "    except gym.error.Error as e:\n",
    "        print(e)\n",
    "\n",
    "    if not os.path.exists(save_dir):\n",
    "        os.makedirs(save_dir)\n",
    "        \n",
    "    state = env.reset()\n",
    "    reward = 0\n",
    "    while True:\n",
    "        qvalues = agent.get_qvalues(np.array([state]))\n",
    "        action = qvalues.argmax(axis=-1)[0]\n",
    "        state, r, done, _ = env.step(action)\n",
    "        reward += r\n",
    "        if done:\n",
    "            print('Got reward: {}'.format(reward))\n",
    "            break\n",
    "            \n",
    "def display_animation(filepath):\n",
    "    video = io.open(filepath, 'r+b').read()\n",
    "    encoded = base64.b64encode(video)\n",
    "    return HTML(data='''<video alt=\"test\" controls>\n",
    "                <source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\" />\n",
    "                 </video>'''.format(encoded.decode('ascii')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Got reward: 332.0\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<video alt=\"test\" controls>\n",
       "                <source src=\"data:video/mp4;base64,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AQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAEAAAAAAIAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAMAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAAAwAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAEAAAAAAIAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAMAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAAAwAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAADAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAACAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAIAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAA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\" type=\"video/mp4\" />\n",
       "                 </video>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Animate learned policy\n",
    "save_dir='./videos/tensorflow/6_3/'\n",
    "env = make_env(env_name)\n",
    "generate_animation(env, agent, save_dir=save_dir)\n",
    "[filepath] = glob.glob(os.path.join(save_dir, '*.mp4'))\n",
    "display_animation(filepath)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO\n",
    "\n",
    "# Try to run this on another environment of your choice from OpenAI Gym\n",
    "# read the accompanying text and try to enahnce the network using various variants\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Summary\n",
    "\n",
    "In this notebook we saw how to train a DQN agent with experience replay and target networks. We can improve this agent with many tricks. As we go along, we will be implementing many of these variants."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
